// $Id: config.cpp 13 2009-05-04 20:00:57Z longerdev $

/*
Copyright (C) 2008 Longer <longerdev@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "config.h"

Config::Config(){
	secsz = 0;
}

int Config::load(const char* fn){
	std::string stmp;
	pcre *re_sec, *re_vk;
	const char *error;
	int erroffset;
	
	fs.open(fn);
	if (!fs)
		return -1;

	re_sec = pcre_compile("^[ \\t]*\\[[ ]*([A-Za-z0-9\\-_]+[ ]*)\\]([ \\t]*|[ \\t]*;.*)$", 0, &error, &erroffset, NULL);
	re_vk = pcre_compile("^[ \\t]*([A-Za-z0-9\\-_]+)[ \\t]*=[ \\t]*([0-9]*|.*)([ \\t]*|[ \\t]*;.*)$", 0, &error, &erroffset, NULL);

	std::string cursec;
	
	while (!fs.eof()){
		int ovector[30];
		int count;

		getline(fs, stmp);
		count = pcre_exec(re_sec, NULL, stmp.c_str(), stmp.length(), 0, 0, ovector, 30);
		if (count != -1){
			cursec = stmp.substr(ovector[2], ovector[3] - ovector[2]);
			if (isNewSec(cursec)){
				sec.push_back(cursec);
				secsz++;
			}
		}
		else{
			count = pcre_exec(re_vk, NULL, stmp.c_str(), stmp.length(), 0, 0, ovector, 30);
			if (count > 0){
				std::string val;
				/*if (stmp.find("\"")){
					val = stmp.substr(ovector[4]+1, ovector[5] - ovector[4]-2);
				}
				else{*/
				val = stmp.substr(ovector[4], ovector[5] - ovector[4]);
				//}
				data[cursec + "::" + stmp.substr(ovector[2], ovector[3] - ovector[2])] = val;
			}
		}
	}

	fs.close();

	if (secsz == 0)
		return 0;
	else
		return secsz;
}

bool Config::isNewSec(const std::string name){
	for (int i = 0; i<secsz; i++)
		if (sec[i] == name)
			return false;

	return true;
}

int Config::getSecCount(){
	return secsz;
}

std::string Config::getValue(const std::string key){
	return data[key];
}

std::string Config::getSection(const int id){
	return sec[id];
}

bool Config::isKey(const std::string key){
	if (data.find(key) == data.end())
			return false;
	return true;
}

